#include <iostream>
#include <string>
#include <memory>
using std::unique_ptr;
using std::string;
using std::cout;
using std::endl;

class RaiseRequest{
public:
    RaiseRequest(int salary, const string& name)
    :_salary(salary)
    ,_name(name)
    {}
    int get_salary()const {
        return _salary;
    }
    
private:
    int _salary;
    string _name;
};

class SalaryApprover{
public:
    SalaryApprover():_nextchain(nullptr){}

    void setnextchain(SalaryApprover *nextchain){
        _nextchain = nextchain;     
    }
    void sendnextchain(const RaiseRequest & request){
        if(_nextchain){
            _nextchain->handleRequest(request);
        }else{
            cout << "raise money " << request.get_salary() <<" nobody agreed " << endl;
        }
    }
    virtual void handleRequest(const RaiseRequest & request)=0;

protected:
    SalaryApprover * _nextchain;
};

class DepartmentManager:public SalaryApprover{
    void handleRequest(const RaiseRequest & request) override{
        if(request.get_salary() < 1000){
            cout << "DepartmentManager agreed raise salary "<< request.get_salary() << endl;
        }else{
            sendnextchain(request); 
        }
    } 
};
class CTO:public SalaryApprover{
    void handleRequest(const RaiseRequest & request) override{
        if(request.get_salary() < 5000){
            cout << "CTO agreed raise salary "<< request.get_salary() << endl;
        }else{
            sendnextchain(request); 
        }
    } 
};
class GeneralManager:public SalaryApprover{
    void handleRequest(const RaiseRequest & request) override{
        if(request.get_salary() < 10000){
            cout << "GeneralManager agreed raise salary "<< request.get_salary() << endl;
        }else{
            sendnextchain(request); 
        } 
        
    }
};


void test(){
    //三个审核对象
    unique_ptr<SalaryApprover> departm(new DepartmentManager());
    unique_ptr<SalaryApprover> cto(new CTO());
    unique_ptr<SalaryApprover> general(new GeneralManager());
    //设置三个审核对象之间的链条关系
    departm->setnextchain(cto.get());
    cto->setnextchain(general.get());
    general->setnextchain(nullptr);
    //几个加薪的例子
    RaiseRequest xiongda(600,"xiongda");
    RaiseRequest xionger(3999,"xiongda");
    RaiseRequest jjgw(9000,"xiongda");
    RaiseRequest gtq(10000,"xiongda");

    departm->handleRequest(xiongda);
    departm->handleRequest(xionger);
    departm->handleRequest(jjgw);
    departm->handleRequest(gtq);
}

int main()
{
    test ();
    return 0;
}

